import ast

from 程序核心代码.mvvm重构.基础定义.基础图形项.基础图形组件.节点基础图形项 import 带布局的节点基础图形项

from 程序核心代码.mvvm重构.ast节点具体实现.数据类节点.数据类节点 import 数据类ast节点基础模型
from 程序核心代码.mvvm重构.基础定义.节点管理器.自动节点注册表 import 注册节点模型, 节点模型匹配器


def 获取属性全名称1(节点):
    """
    递归提取 ast.Attribute 节点的全名称。

    参数:
    - 节点模型: 一个 ast.Attribute 节点模型

    返回:
    - 包含属性全名称的字符串
    """
    if isinstance(节点, ast.Attribute):
        # 如果节点是 Attribute 类型，递归获取其 value 的全名称并附加上 attr
        #return f"{获取属性全名称(节点模型.value)}.{节点模型.attr}"
        return f"{获取起始变量(节点.value)}.{节点.attr}"
    elif isinstance(节点, ast.Name):
        # 如果节点是 Name 类型，返回其 id
        return 节点.id
    elif isinstance(节点, ast.Call):
        # 如果节点是函数调用，获取函数名以及调用后的内容
        名称 = f"{获取属性全名称(节点.func)}()"
       # print(名称)
        return 名称
    elif isinstance(节点, ast.Subscript):
        # 处理下标访问，如 obj[0].attr
        return f"{获取属性全名称(节点.value)}[{ast.dump(节点.slice)}]"
    elif isinstance(节点, ast.Constant):
        # 如果节点是常量类型，返回其值
        #print("节点类型为常量")
        return repr(节点.value)
    else:
        raise ValueError(f"不支持的节点类型: {type(节点)}")
def 获取属性全名称(节点):
    """
    递归提取 ast.Attribute 节点的全名称。

    参数:
    - 节点模型: 一个 ast.Attribute 节点模型

    返回:
    - 包含属性全名称的字符串列表
    """
    if isinstance(节点, ast.Attribute):
        # 如果节点是 Attribute 类型，递归获取其 value 的全名称并附加上 attr
        return 获取属性全名称(节点.value) + [节点.attr]
    elif isinstance(节点, ast.Name):
        # 如果节点是 Name 类型，返回其 id
        return [节点.id]
    elif isinstance(节点, ast.Call):
        # 如果节点是函数调用，获取函数名并在末尾加上 '()' 表示调用
        return 获取属性全名称(节点.func) + ['()']
    elif isinstance(节点, ast.Subscript):
        # 处理下标访问，如 obj[0].attr
        return 获取属性全名称(节点.value) + [f"[{ast.dump(节点.slice)}]"]
    elif isinstance(节点, ast.Constant):
        # 如果节点是常量类型，返回其值
        return [repr(节点.value)]
    else:
        raise ValueError(f"不支持的节点类型: {type(节点)}")

def 获取起始变量(节点):
    """
    递归提取 ast.Attribute 节点的全名称。

    参数:
    - 节点模型: 一个 ast.Attribute 节点模型

    返回:
    - 包含属性全名称的字符串
    """

    if isinstance(节点, ast.Attribute):
        # 如果节点是 Attribute 类型，递归获取其 value 的全名称并附加上 attr

        return 获取起始变量(节点.value)
    elif isinstance(节点, ast.Name):
        # 如果节点是 Name 类型，返回其 id
        return 节点.id
    elif isinstance(节点, ast.Call):
        # 如果节点是函数调用，获取函数名以及调用后的内容
        return 获取起始变量(节点.func)
    elif isinstance(节点, ast.Subscript):
        # 处理下标访问，如 obj[0].attr
        return 获取起始变量(节点.value)
    else:
        raise ValueError(f"不支持的节点类型: {type(节点)}")

@注册节点模型(ast.Attribute)
class 属性节点(数据类ast节点基础模型):

    def 节点数据解析(self):
        self.属性全名称 = 获取属性全名称(self._ast节点)
        self.属性的前级节点属性全名称 = self.属性全名称[:-1]
        self.起始节点=self.属性全名称[0]
        self.参数名称="属性名："
        self.操作类型 = self._ast节点.ctx
        if self.操作类型 == ast.Store:
            #起始接口.获取属性("节点名称") = "存储节点"
            self.是否显示 = True
        elif self.操作类型 == ast.Load:
            if not self.是否显示:
                self.是否显示 = False
    def 参数值初始函数(self):
        return self._ast节点.attr
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点=None,节点位置=None):
        super().__init__(ast节点, 所属节点模型管理器,  节点名称="属性节点",节点位置=节点位置,上级节点=上级节点)

        # 起始接口.基础图形项 = 属性节点图形项( 起始接口)
        # #print(起始接口.节点标题名称)
        self.属性列表 = None
        self.属性的前级节点= None
        self.属性创建前级节点()
        self.同用处ast节点列表 = []
        #起始接口.节点关系检查()

    def 属性的上级节点变化(self):
        print("属性的前级节点变化", 获取属性全名称(self._ast节点))
        print("同用处ast节点列表：",self.同用处ast节点列表)
        for _ast节点 in self.同用处ast节点列表:
            print("同表：",获取起始变量(_ast节点))
            self.同步属性id(_ast节点.value, self._ast节点.value)
        #pass

    def 同步属性id(self,目标节点, 参考节点):
        """递归地同步目标节点中所有与参考节点结构相同的 .id 图形项属性"""
        if isinstance(目标节点, ast.Attribute) and isinstance(参考节点, ast.Attribute):
            if hasattr(参考节点.value, 'id') and hasattr(目标节点.value, 'id'):
                目标节点.value.id = 参考节点.value.id  # 同步 id
            # 递归地同步嵌套的 .value
            self.同步属性id(目标节点.value, 参考节点.value)

    def 节点关系检查(self):
        #同级节点=
        #属性是个连续列表 应该匹配每一个部分， 如果是有部分差异 那么差异部分就应该生成信息的节点
        # if 起始接口.属性全名称!=获取属性全名称(起始接口._ast节点):
        #     #起始接口.属性的上级节点变化()
        #     起始接口.节点数据解析()
        同级节点 =super().节点关系检查()
        if not 同级节点:
        #     起始接口.属性的上级节点=同级节点
        #     #起始接口.上级节点检查()
        # else:
            self.属性创建上级节点()
        #起始接口.上级节点检查()
        else:
            self.属性的上级节点=同级节点
        if self.属性的上级节点:
            print("属性的上级节点：", self.属性的上级节点)
            # 起始接口.添加接口到节点("数据流", "输入", 接口名称="数据输入", 必须连接=False)
            # 起始接口.添加接口到节点("数据流", "输出", 接口名称="数据输出", 必须连接=False)
            结束接口 = self.添加接口到节点("调用流", "输入", 必须连接=False)
            起始接口 = self.属性的上级节点.添加接口到节点("调用流", "输出", 必须连接=False)
            起始接口.接口创建连接线模型(结束接口, self)

        # if 起始接口.属性的上级节点:
        #
        # else:
        #     raise Exception("上级节点创建失败", 起始接口.属性的上级节点)
        # # print(ast.dump(起始接口._ast节点, annotate_fields=True, indent=4))

        else:
            print("上级节点识别失败")


    def 属性创建前级节点(self):
        self.属性的前级节点=self.前级节点搜索()
        if self.属性的前级节点:
            self.同用处ast节点列表.append(self._ast节点.value)
        else:
            self.属性的前级节点 = 节点模型匹配器(self._ast节点.value, self.所属节点模型管理器, 上级节点=self)
        结束接口 = self.添加接口到节点("调用流", "输入", 必须连接=False)
        起始接口 = self.属性的前级节点.添加接口到节点("调用流", "输出", 必须连接=False)
        起始接口.接口创建连接线模型(结束接口, self)

    def 前级节点搜索(self):
        前级数据节点=None
        for 节点 in self.所属节点模型管理器.节点模型列表:
            前级数据节点=self.前级检查规则(节点)
            if 前级数据节点 and 前级数据节点!=self:
                break
        return 前级数据节点
    def 前级检查规则(self, 节点):
        # 实际为上级节点检查
        if hasattr(节点, "属性全名称") and (节点.属性全名称 == self.属性的前级节点属性全名称):
            if self != 节点:
                return 节点
        #检查变量节点 并检查其上级节点不能为属性
        return None
    def 参数名检测(self, 参数名):
        if self.属性列表:

            return 参数名 in self.属性列表
        return False
    def 数据节点参数值修改(self, 新参数):
        self.图形项.节点参数.更改当前选中(新参数)
        self._ast节点.attr = 新参数
        for ast节点 in self.同步ast节点列表:
            ast节点.attr = 新参数

    def 删除节点(self,要删除的节点=None):
        节点 = ast.Expr(self.属性的上级节点._ast节点)
        self.所属节点模型管理器.ast操作器.插入节点(self.所属节点模型管理器.创建者节点.节点路径, 节点)
        super().删除节点()


class 属性节点图形项(带布局的节点基础图形项):
    def __init__(self, 节点定义, 父项=None):
        super().__init__(节点定义, 父项)
        #起始接口.节点定义.节点介绍 = 起始接口.节点定义.节点名称+"：默认介绍"
